﻿using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Windows.Forms;
using ICSharpCode.SharpZipLib.Zip;
using System.Data.SqlServerCe;
using EnterpriseDT.Net.Ftp;
using System.IO;
using System.Security;
using System.Security.Permissions;
using System.Security.Cryptography;

namespace CPTECH.Business
{
    class SendFtpBO
    {
        SqlCeConnection conn = new SqlCeConnection(@"Data Source=" + (System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase) + "\\dbInventario.sdf;"));    
        String batch = (System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase) + "\\BatchFiles");
        String backUP = (System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase) + "\\BackUP");

        private static SendFtpBO instance;

        private SendFtpBO() { }

        public static SendFtpBO getInstance()
        {
            if (instance == null)
            {
                instance = new SendFtpBO();
            }
            return instance;
        }

        //Metodo que envia os lotes criados
        public void EnviaDados()
        {
            FTPConnection ftp = new FTPConnection();
            ftp.LicenseOwner = "CPCON";
            ftp.LicenseKey = "042-3705-7475-5624";
            ftp.ServerAddress = "74.208.171.61";
            ftp.UserName = "alex";
            ftp.Password = "xc38ak76";


            ftp.Connect();
            if (ftp.IsConnected)
            {
                MessageBox.Show("Conectado! Agurade o Envio dos Dados");
            }
            else
            {
                MessageBox.Show("Não foi possível estabelecer uma conexão, verifique as configurações da mesma!","Conexão");
            }

            String[] LSFiles = Directory.GetFiles(batch, "*.LS");
            ftp.TransferType = FTPTransferType.BINARY;
            for (int i = 0; i < LSFiles.Length; i++)
            {
                ftp.UploadFile(LSFiles[i], LSFiles[i].Replace(batch+"\\", "").Replace(".LS", ".ZIP"));
                //System.IO.File.Move(LSFiles[i].Replace(".ZIP",".LS"), LSFiles[i].Replace(".ZIP",".LF"));
            }


            LSFiles = Directory.GetFiles(batch, "*.MD5");
            ftp.TransferType = FTPTransferType.ASCII;
            for (int i = 0; i < LSFiles.Length; i++)
            {
                ftp.UploadFile(LSFiles[i], LSFiles[i].Replace(batch+"\\", ""));
                System.IO.File.Move(LSFiles[i], LSFiles[i].Replace(".MD5", ".MDF"));
            }

            LSFiles = Directory.GetFiles(batch, "*.LS");
            for (int i = 0; i < LSFiles.Length; i++)
            {
                System.IO.File.Move(LSFiles[i], LSFiles[i].Replace(".LS", ".LF"));
            }
            ftp.Close();

        }

        public void criarMd5File(String fileName)
        {
            String hashMd5 = getFilesMD5Hash(fileName);
            try
            {
                StreamWriter sw = new StreamWriter(fileName.Replace(".LS", ".MD5"));
                sw.Write(hashMd5);
                sw.Close();
            }
            catch (System.IO.IOException e)
            {
                MessageBox.Show(e.Message);
            }
        }

        public string getFilesMD5Hash(string file)
        {
            MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
            FileStream stream = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read, 8192);
            md5.ComputeHash(stream);
            stream.Close();
            byte[] hash = md5.Hash;
            StringBuilder sb = new StringBuilder();
            foreach (byte b in hash)
            {
                sb.Append(string.Format("{0:X2}", b));
            }
            return sb.ToString();
        }

        //Metodoto que lista os lotes gerados
        public ArrayList ListaLote()
        {
            String[] LSFiles = Directory.GetFiles(batch, "*.LS");
            ArrayList lotes = new ArrayList();
            for (int i = 0; i < LSFiles.Length; i++)
            {
                //criarMd5File(LSFiles[i]);
                //compressFile(LSFiles[i]);
                lotes.Add(LSFiles[i]);
            }
            return lotes;
        }

        public void compressFile(String filename)
        {
            ZipFile z = ZipFile.Create(filename.Replace(".LS", ".ZIP"));
            z.BeginUpdate();
            z.Add(filename);
            z.CommitUpdate();
            z.Close();
        }

        //Metodo que verifica se a base esta vazia ou não, se sim gera o lote senão acusa base vazia.
        public void GerarLote()
        {
            if (!Directory.Exists(batch))
            {
                Directory.CreateDirectory(batch);
            }

            if (!Directory.Exists(backUP))
            {
                Directory.CreateDirectory(backUP);
            }

            string query = "SELECT count(1) FROM tb_fisico where enviado = '0';";
            SqlCeCommand cmd = new SqlCeCommand(query, conn);
            int val1 = 0;
            conn.Open();
            SqlCeDataReader rdr = cmd.ExecuteReader();
            try
            {
                while (rdr.Read())
                {
                    val1 = rdr.GetInt32(0);
                }
            }
            finally
            {
                rdr.Close();
                conn.Close();
            }
            if (val1 == 0)
            {
                MessageBox.Show("Base vazia!");
            }
            
            else
            {
                MessageBox.Show("Gerando lote, Aguarde!");

                geraArquivo();

                //cria arquivo .zip e md5.
                String[] LSFiles = Directory.GetFiles(batch, "*.LS");
                for (int i = 0; i < LSFiles.Length; i++)
                {
                    criarMd5File(LSFiles[i]);
                    compressFile(LSFiles[i]);
                }
               // limpaBase();
            }
        }

        public string getLogin()
        {
            string login = FisicoBO.getInstance().idPalm;
            //string query = "SELECT distinct(id_palm) FROM tb_fisico";
            //SqlCeCommand cmd = new SqlCeCommand(query, conn);
            //string login = "";
            //conn.Open();
            //SqlCeDataReader rdr = cmd.ExecuteReader();
            //try
            //{
            //    while (rdr.Read())
            //    {
            //        login = rdr.GetString(0);
            //    }
            //}
            //finally
            //{
            //    rdr.Close();
            //    conn.Close();
            //}
            //return login.Replace(".", "_");
            return login;
        }

        public string getProgramacao()
        {
            string prog = FisicoBO.getInstance().os;
            //string query = "SELECT distinct os from tb_fisico;";

            //SqlCeCommand cmd = new SqlCeCommand(query, conn);
            //String prog = "";
            //conn.Open();
            //SqlCeDataReader rdr = cmd.ExecuteReader();
            //try
            //{
            //    while (rdr.Read())
            //    {
            //        prog = rdr.GetString(0);
            //    }
            //}
            //finally
            //{
            //    rdr.Close();
            //    conn.Close();
            //}
            return prog;
        }

        //Metodo que Gera o arquivo(lote)
        private void geraArquivo()
        {
            MessageBox.Show("iniciou a geracao");
            string programacao = getProgramacao();
            string fileName = batch+"\\" + programacao + "_" + getLogin() + "_" + DateTime.Now.ToString("ddMMyyyyhhmmss") + ".LS";

            TextWriter tw = new StreamWriter(fileName);

            string query = "SELECT * FROM tb_fisico where enviado = '0';";
            SqlCeCommand cmd = new SqlCeCommand(query, conn);
            conn.Open();
            SqlCeDataReader rdr = cmd.ExecuteReader();
            string line = "";
            int contador = 0;
            try
            {
                while (rdr.Read())
                {
                    contador++;
                    try
                    {

                        line = //programacao + "¶" +
                                rdr[0] + "¶" +
                                rdr[1] + "¶" +
                                rdr[2] + "¶" +
                                rdr[3] + "¶" +
                                rdr[4] + "¶" +
                                rdr[5] + "¶" +
                                rdr[6] + "¶" +
                                rdr[7] + "¶" +
                                rdr[8] + "¶" +
                                rdr[9] + "¶" +
                                rdr[10] + "¶" +
                                rdr[11] + "¶" +
                                rdr[12] + "¶" +
                                rdr[13] + "¶" +
                                rdr[14] + "¶" +
                                rdr[15] + "¶" +
                                rdr[16] + "¶" +
                                rdr[17] + "¶" +
                                rdr[18] + "¶" +
                                rdr[19] + "¶" +
                                rdr[20] + "¶" +
                                rdr[21] + "¶" +
                                rdr[22] + "¶" +
                                rdr[23] + "¶" +
                                rdr[24] + "¶" +
                                rdr[25] + "¶" +
                                rdr[26] + "¶" +
                                rdr[27] + "¶" +
                                rdr[28] + "¶" +
                                rdr[29] + "¶" +
                                rdr[30] + "¶" +
                                rdr[31];
                    }
                    catch (SqlCeException e)
                    {
                        MessageBox.Show(e.Message);
                    }
                    catch (IndexOutOfRangeException e)
                    {
                        MessageBox.Show(e.Message);
                    }
                    tw.WriteLine(line);
                }
            }
            finally
            {
                rdr.Close();
                conn.Close();
            }
            tw.WriteLine("Quantidade Total de registros:" + contador);
            tw.Close();
            MessageBox.Show("Geração finalizada com sucesso!","Gerar Lote");

        }

        //Metodo que limpa a Base de dados
        private void limpaBase()
        {
            MessageBox.Show("Limpar a Base");
            conn.Open();
            SqlCeCommand sqlDelete = conn.CreateCommand();
            sqlDelete.CommandText = "DELETE FROM tb_fisico";
            sqlDelete.ExecuteNonQuery();
            conn.Close();
            MessageBox.Show("Base Limpa com sucesso");

        }
    }
}
